﻿using System;
using System.Collections.Concurrent;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading;
using Raven.Abstractions.Commands;
using Raven.Abstractions.Data;
using Raven.Json.Linq;
using Topics.Radical.ComponentModel.Messaging;
using Topics.Radical.Helpers;
using Topics.Radical.Validation;

namespace SampleApp.MvcBackend.Runtime
{
	abstract class DispatchConsumer<T> where T: class
	{
		readonly BlockingCollection<T> queue = new BlockingCollection<T>();
		
		protected DispatchConsumer()
		{
			
			var scheduler = new EventLoopScheduler( ts =>
			{
				var thread = new Thread( ts )
				{
					IsBackground = true,
				};

				return thread;
			} );

			this.queue.GetConsumingEnumerable()
				.ToObservable( scheduler )
				.Subscribe( item =>
				{
					try
					{
						this.Dispatch( item );
					}
					catch ( Exception ex )
					{
						//TODO: Log
					}
				} );
		}

		protected abstract void Dispatch( T item );

		public void ScheduleDispatch( T item )
		{
			Ensure.That( item ).Named( () => item ).IsNotNull();

			this.queue.Add( item );
		}
	}
}
